package com.hu;

import java.util.*;
import java.util.stream.Collectors;

import static com.hu.Stream01.getAuthors;

/**
 * @author 00355760
 * @功能：
 * @版本： V1
 * @版权： 信息技术有限公司（http://www.mychery.com/）
 * @作者： 磐石战队开发组  00355760
 * @日期： 2024/9/14 14:58
 */
public class Stream02 {

    public static void main(String[] args) {
        List<Author> authors = getAuthors();

        /**
         * 中间操作
         */
        //获取所有姓名长度大于1的作家的名字 filter
        authors.stream().filter(author->author.getName().length()>1).forEach(author->System.out.println(author.getName()));
        //获取所有作家的姓名 map
        authors.stream().map(Author::getName).forEach(System.out::println);
        authors.stream().map(Author::getAge).map(age->age+1).forEach(System.out::println);
        //获取所有作家的姓名，不能有重复元素 distinct
        authors.stream().map(Author::getName).distinct().forEach(System.out::println);
        //按照年龄进行降序排序，不能有重复元素 sorted---调用空参sorted方法，需要重写实现comparable
        authors.stream().distinct().sorted().forEach(author -> System.out.println(author.getAge()));
        //按照年龄进行降序排序，不能有重复元素 sorted---调用有参sorted方法
        authors.stream().distinct().sorted((o1, o2) -> o2.getAge()-o1.getAge()).forEach(author -> System.out.println(author.getAge()));
        //上一步中打印年龄最大的两个作家的名字 limit
        authors.stream().distinct().sorted((o1, o2) -> o2.getAge()-o1.getAge()).limit(2).forEach(author -> System.out.println(author.getName()));
        //打印除了年龄最大的，并降序排列，即跳过某一个元素 skip
        authors.stream().distinct().sorted().skip(1).forEach(author -> System.out.println(author.getName()));
        //获取所有书籍的名字并去重 flatMap：把一个对象转换为多个对象作为流中的元素
        authors.stream().distinct().flatMap(author -> author.getBooks().stream()).distinct().forEach(System.out::println);
        //获取数据的所有分类并去重，不能出现这种：哲学，爱情。字符串数组需要用Arrays.stream()
        authors.stream().distinct().flatMap(author -> author.getBooks().stream().map(Book::getCategory)).distinct().forEach(System.out::println);
        authors.stream().distinct().flatMap(author -> author.getBooks().stream()).flatMap(book -> Arrays.stream(book.getCategory().split(","))).distinct().forEach(s -> System.out.println(s));

        /**
         * 终结操作
         */
        //获取作家所出书籍的总数，注意剔除重复元素 count
        long count = authors.stream().flatMap(author -> author.getBooks().stream()).distinct().count();
        System.out.println(count);
        //分别获取作家所出书籍的最高分和最低分 max和min
        Optional<Integer> max = authors.stream().flatMap(author -> author.getBooks().stream()).map(Book::getScore).max(Comparator.comparingInt(o -> o));
        max.ifPresent(System.out::println);
        Optional<Integer> min = authors.stream().flatMap(author -> author.getBooks().stream()).map(Book::getScore).min(Comparator.comparingInt(o -> o));
        min.ifPresent(System.out::println);
        //获取一个存放所有作者名字的list集合
        //获取一个存放所有书的名字的set集合
        //获取一个存放所有Name:List<Book>的map集合
        List<String> collect = authors.stream().map(Author::getName).collect(Collectors.toList());
        System.out.println(collect);
        Set<Book> collect1 = authors.stream().flatMap(book->book.getBooks().stream()).collect(Collectors.toSet());
        System.out.println(collect1);
        Map<String, List<Book>> collect2 = authors.stream().distinct().collect(Collectors.toMap(author -> author.getName(), author -> author.getBooks()));
        System.out.println(collect2);
        //查找与匹配
        //判断是否有29岁以上的作家 anyMatch
        boolean b = authors.stream().anyMatch(author -> author.getAge() > 29);
        System.out.println(b);
        //判断所有作家是否都是成年人 allMatch
        boolean b1 = authors.stream().allMatch(author -> author.getAge() > 18);
        System.out.println(b1);
        //判断是否都没有超过100岁 noneMatch
        boolean b2 = authors.stream().noneMatch(author -> author.getAge() > 100);
        System.out.println(b2);
        //获取任意一个大于18的，存在就输出名字 findAny:任意一个 注意，并行流中，findAny和findFirst不是绝对的，可能返回一个null
        authors.stream().filter(author -> author.getAge() > 18).findAny().ifPresent(author -> System.out.println(author.getName()));
        //获取一个年龄最小的，并输出姓名 findFirst:第一个
        authors.stream().sorted().findFirst().ifPresent(author -> System.out.println(author.getName()));

        //reduce归并：将流中的元素按照指定的计算方式组合起来得到一个结果
        //求所有作者的年龄和
        Integer reduce = authors.stream().distinct().map(Author::getAge).reduce(0, Integer::sum);
        System.out.println(reduce);
        //求所有作者的年龄中的最小值
        Optional<Integer> reduce1 = authors.stream().map(Author::getAge).reduce(Integer::min);
        Optional<Integer> reduce4 = Optional.of(authors.stream().map(Author::getAge).reduce(Integer.MAX_VALUE, (integer, integer2) -> integer < integer2 ? integer : integer2));

        reduce1.ifPresent(System.out::println);
        reduce4.ifPresent(System.out::println);
        //求所有作者的年龄中的最大值
        Optional<Integer> reduce2 = authors.stream().map(Author::getAge).reduce(Integer::max);
        Optional<Integer> reduce3 = Optional.of(authors.stream().map(Author::getAge).reduce(Integer.MIN_VALUE, (integer, integer2) -> integer > integer2 ? integer : integer2));
        reduce2.ifPresent(System.out::println);
        reduce3.ifPresent(System.out::println);
    }
}
